package com.rzl.expense.framework.security.sso;

import com.rzl.expense.common.core.domain.entity.SysUser;
import com.rzl.expense.common.exception.ServiceException;
import com.rzl.expense.common.utils.StringUtils;
import com.rzl.expense.framework.web.service.UserDetailsServiceImpl;
import com.rzl.expense.system.service.ISysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;

import java.util.Collections;

/**
 * sso身份验证提供商
 *
 * @author admin
 * @date 2023/09/19
 */
@Component
public class SSOAuthenticationProvider implements AuthenticationProvider {
    @Autowired
    private UserDetailsServiceImpl userDetailsService;

    @Autowired
    private ISysUserService userService;

    /**
     * 认证逻辑
     */
    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        SSOAuthenticationToken sooAuthenticationToken = (SSOAuthenticationToken) authentication;
        //获取到的smapId
        String smapId = (String) sooAuthenticationToken.getPrincipal();
        //根据这个smapid查询用户
        SysUser sysUser = userService.selectUserBySmapId(smapId);
        if (StringUtils.isNull(sysUser)) {
            throw new ServiceException("用户：" + smapId + " 不存在");
        }
        UserDetails user = userDetailsService.loadUserByUsername(sysUser.getUserName());
        SSOAuthenticationToken result = new SSOAuthenticationToken(user, Collections.emptyList());
        /*
        Details 中包含了 ip地址、 sessionId 等等属性 也可以存储一些自己想要放进去的内容
        */
        result.setDetails(sooAuthenticationToken.getDetails());
        return result;
    }

    /**
     * UserIdAuthenticationToken交给UserIdAuthenticationProvider处理
     *
     * @param aClass
     * @return
     */
    @Override
    public boolean supports(Class<?> aClass) {
        return SSOAuthenticationToken.class.isAssignableFrom(aClass);

    }
}
